home *** CD-ROM | disk | FTP | other *** search
- #! /usr/bin/python
- # -*- coding: utf-8 -*-
- #
- # © 2005 Josselin Mouette <joss@debian.org>
- # Licensed under the GNU LGPL, see /usr/share/common-licenses/LGPL-2.1
-
- treefile = '%gconf-tree.xml'
-
- import os,tempfile,shutil,sys
- from optparse import OptionParser
-
- parser = OptionParser()
- parser.add_option("--source", dest="source_dir", default="/usr/share/gconf/defaults",
- help="directory where to find the defaults", metavar="DIR")
- parser.add_option("--destination", dest="dest_dir", default="/var/lib/gconf/debian.defaults",
- help="directory where to build the GConf tree", metavar="DIR")
- parser.add_option("--mandatory", action="store_true", default=False, dest="mandatory",
- help="select mandatory settings directories")
- parser.add_option("--no-signal", action="store_false", default=True, dest="signal",
- help="do not send SIGHUP the running gconfd-2 processes")
- parser.add_option("--only-if-changed", action="store_true", default=False, dest="ifchanged",
- help="only regenerate configuration if needed")
-
- (options, args) = parser.parse_args()
-
- if options.mandatory:
- options.source_dir="/usr/share/gconf/mandatory"
- options.dest_dir="/var/lib/gconf/debian.mandatory"
-
- if not os.path.isdir(options.source_dir):
- parser.error("Source directory does not exist.")
- if not os.path.isdir(options.dest_dir):
- parser.error("Destination directory does not exist.")
- if not os.access(options.source_dir,os.R_OK|os.X_OK):
- parser.error("Source directory is not readable.")
- if not os.access(options.dest_dir,os.W_OK|os.X_OK):
- parser.error("Destination directory is not writable.")
-
- save_stdout=os.dup(1)
- os.close(1)
-
- def cleanup():
- os.dup2(save_stdout,1)
- os.close(save_stdout)
- shutil.rmtree(tmp_dir)
-
- def htmlescape(str):
- return str.replace('&','&').replace('>','>').replace('<','<').replace('"','"')
-
- def int_entry(value):
- return ' <int>' + value + '</int>\n'
-
- def bool_entry(value):
- return ' <bool>' + value + '</bool>\n'
-
- def float_entry(value):
- return ' <float>' + value + '</float>\n'
-
- def string_entry(value):
- return ' <string>' + htmlescape(value) + '</string>\n'
-
- def list_entry(value):
- ret = ' <list type="string">\n'
- for v in value[1:-1].split(','):
- ret += ' <value><string>' + htmlescape(v) + '</string></value>\n'
- ret += ' </list>\n'
- return ret
-
-
- def listcmp(a,b):
- """Number of starting similar elements in a and b"""
- m = min(len(a),len(b))
- for i in range(m):
- if a[i] != b[i]:
- return i
- return m
-
- def apply_entries(filename):
- res=os.spawnvpe(os.P_WAIT,'gconftool-2',
- ['gconftool-2','--direct','--config-source',
- 'xml:merged:'+tmp_gconf,'--load',filename],
- {'HOME': tmp_home})
- if res:
- cleanup()
- sys.exit(res)
-
- gconf_val = {}
-
- def write_and_apply_entries(filename):
- out=file(filename,'w')
- out.write('<gconfentryfile>\n<entrylist base="/">\n')
- for key in gconf_val:
- out.write('<entry>\n<key>' + key + '</key>\n<value>\n')
- # write the current entry
- value = gconf_val[key]
- if value[0] == '"' and value[-1] == '"':
- out.write(string_entry(value[1:-1]))
- elif value in ['true','false']:
- out.write(bool_entry(value))
- elif value[0] == '[' and value[-1] == ']':
- out.write(list_entry(value))
- elif value.isdigit():
- out.write(int_entry(value))
- else:
- try:
- float(value)
- out.write(float_entry(value))
- except ValueError:
- out.write(string_entry(value))
- out.write('</value>\n</entry>\n')
- out.write('</entrylist>\n</gconfentryfile>\n')
- out.close()
- apply_entries(filename)
-
- def read_entries(filename):
- for line in file(filename):
- l = line.rstrip('\n').split(None,1)
- if len(l) == 2 and not l[0].startswith('#'):
- gconf_val[l[0]] = l[1]
-
-
- defaults_files = []
- for f in os.listdir(options.source_dir):
- for ext in ['.dpkg-tmp', '.bak', '.tmp', '~', '.sav', '.save']:
- if f.endswith(ext):
- break
- else:
- defaults_files.append(f)
- defaults_files.sort()
-
- if options.ifchanged:
- source_stamp = os.stat(options.source_dir).st_mtime
- for f in defaults_files:
- realname=os.path.join(options.source_dir,f)
- source_stamp = max(os.stat(realname).st_mtime,source_stamp)
- try:
- dest_stamp = os.stat(os.path.join(options.dest_dir, treefile)).st_mtime
- except OSError:
- dest_stamp = 0
- if source_stamp < dest_stamp:
- sys.exit(0)
-
- tmp_dir=tempfile.mkdtemp(prefix="gconf-")
- tmp_home=tmp_dir+'/home'
- tmp_gconf=tmp_dir+'/gconf'
- tmp_file=tmp_dir+'/temp.entries'
-
- for f in defaults_files:
- realname=os.path.join(options.source_dir,f)
- if f.endswith('.entries'):
- if gconf_val:
- write_and_apply_entries(tmp_file)
- gconf_val={}
- apply_entries(realname)
- else:
- read_entries(realname)
- if gconf_val:
- write_and_apply_entries(tmp_file)
-
- try:
- shutil.copyfile(tmp_gconf+'/'+treefile,options.dest_dir+'/'+treefile+'.tmp')
- os.rename(options.dest_dir+'/'+treefile+'.tmp',options.dest_dir+'/'+treefile)
- except IOError:
- # No %gconf-tree.xml file was created.
- try:
- os.remove(options.dest_dir+'/'+treefile)
- except OSError:
- # No existing file
- pass
-
- cleanup()
-
- if options.signal:
- os.system('kill -s HUP `pidof gconfd-2` >/dev/null 2>&1')
-